package com.ruoyi.doorcontrol.service.impl;

import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.doorcontrol.commom.osSelect;
import com.ruoyi.doorcontrol.sdk.HCNetSDK;
import com.sun.jna.Native;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.doorcontrol.mapper.ThDoorControlMapper;
import com.ruoyi.doorcontrol.domain.ThDoorControl;
import com.ruoyi.doorcontrol.service.IThDoorControlService;

import static com.ruoyi.common.constant.ControlStatus.DENGLU;
import static com.ruoyi.common.constant.ControlStatus.TUICHU;

/**
 * 门禁管理Service业务层处理
 * 
 * @author zhang
 * @date 2024-07-13
 */
@Service
public class ThDoorControlServiceImpl implements IThDoorControlService 
{

    static HCNetSDK hCNetSDK = HCNetSDK.INSTANCE;
    public static ConcurrentHashMap<String, Integer> loginHandleMap = new ConcurrentHashMap<>();
    public static ConcurrentHashMap<Integer, Integer> encodeMap = new ConcurrentHashMap<>();
    public static int lUserID = -1;//用户句柄
    static int iCharEncodeType = 0;//设备字符集
    @Autowired
    private ThDoorControlMapper thDoorControlMapper;

    /**
     * 查询门禁管理
     * 
     * @param id 门禁管理主键
     * @return 门禁管理
     */
    @Override
    public ThDoorControl selectThDoorControlById(Long id)
    {
        return thDoorControlMapper.selectThDoorControlById(id);
    }

    /**
     * 查询门禁管理列表
     * 
     * @param thDoorControl 门禁管理
     * @return 门禁管理
     */
    @Override
    public List<ThDoorControl> selectThDoorControlList(ThDoorControl thDoorControl)
    {
        return thDoorControlMapper.selectThDoorControlList(thDoorControl);
    }

    /**
     * 新增门禁管理
     * 
     * @param thDoorControl 门禁管理
     * @return 结果
     */
    @Override
    public int insertThDoorControl(ThDoorControl thDoorControl)
    {
        thDoorControl.setCreateTime(DateUtils.getNowDate());
        return thDoorControlMapper.insertThDoorControl(thDoorControl);
    }

    /**
     * 修改门禁管理
     * 
     * @param thDoorControl 门禁管理
     * @return 结果
     */
    @Override
    public int updateThDoorControl(ThDoorControl thDoorControl)
    {
        return thDoorControlMapper.updateThDoorControl(thDoorControl);
    }

    /**
     * 批量删除门禁管理
     * 
     * @param ids 需要删除的门禁管理主键
     * @return 结果
     */
    @Override
    public int deleteThDoorControlByIds(Long[] ids)
    {
        return thDoorControlMapper.deleteThDoorControlByIds(ids);
    }

    /**
     * 删除门禁管理信息
     * 
     * @param id 门禁管理主键
     * @return 结果
     */
    @Override
    public int deleteThDoorControlById(Long id)
    {
        return thDoorControlMapper.deleteThDoorControlById(id);
    }

    @Override
    public AjaxResult login(Long id) {
        if(hCNetSDK == null)
        {
            if(!createSDKInstance())
            {
                System.out.println("Load SDK fail");
                return AjaxResult.error("Load SDK fail");
            }
        }
        ThDoorControl control = new ThDoorControl();
        control.setStatus(1);
        /*List<ThDoorControl> thDoorControls = thDoorControlService.selectThDoorControlList(control);
        if(thDoorControls.size()>0){
            throw new CustomException("已有门禁登录！");
        }*/
        ThDoorControl thDoorControl = thDoorControlMapper.selectThDoorControlById(id);
        AjaxResult login = login_V40(thDoorControl.getIpadress(),thDoorControl.getUser(),thDoorControl.getPsw(),thDoorControl.getPort());
        if(200 == Integer.parseInt(login.get("code").toString())){
            thDoorControl.setStatus(DENGLU);
            thDoorControlMapper.updateThDoorControl(thDoorControl);
        }

        return login;
    }

    @Override
    public AjaxResult logout2(Long id) {
        ThDoorControl thDoorControl = thDoorControlMapper.selectThDoorControlById(id);
        thDoorControl.setStatus(TUICHU);
        Integer loginHandler = loginHandleMap.get(thDoorControl.getIpadress());
        if(null == loginHandler){
            thDoorControlMapper.updateThDoorControl(thDoorControl);
            System.out.println(thDoorControl.getNotes()+"没有登录信息！！！");
            return AjaxResult.success(thDoorControl.getNotes()+"没有登录信息！！！");
        }
        /**登出和清理，释放SDK资源*/
        if (loginHandler>=0)
        {
            if (!hCNetSDK.NET_DVR_Logout(loginHandler))
            {
                System.out.println("设备注销失败，错误码：" + hCNetSDK.NET_DVR_GetLastError());
                return AjaxResult.error();
            }
            System.out.println("设备注销成功！！！");
        }
        thDoorControlMapper.updateThDoorControl(thDoorControl);
        AjaxResult ajaxResult = new AjaxResult();
        ajaxResult.put("code",200);
        ajaxResult.put("msg","退出成功！");
        return ajaxResult;
    }

    @Override
    public ThDoorControl selectThDoorControlByIp(String ip) {
        return thDoorControlMapper.selectThDoorControlByIp(ip);
    }

    @Override
    public ThDoorControl selectcontrolByPositionAndType(String menfang, String type) {
        return thDoorControlMapper.selectcontrolByPositionAndType(menfang,type);
    }

    /**
     * 根据不同操作系统选择不同的库文件和库路径
     * @return
     */
    public boolean createSDKInstance()
    {
        if(hCNetSDK == null)
        {
            synchronized (HCNetSDK.class)
            {
                String strDllPath = "";
                try
                {
                    //System.setProperty("jna.debug_load", "true");
                    if(osSelect.isWindows())
                        //win系统加载库路径
                        strDllPath = System.getProperty("user.dir") + "\\lib\\HCNetSDK.dll";
                    else if(osSelect.isLinux())
                        //Linux系统加载库路径
                        strDllPath =  System.getProperty("user.dir") + "/lib/libhcnetsdk.so";


                    //System.out.println(">>>"+com.sun.jna.examples.win32.W32Errors.class);

                    hCNetSDK = (HCNetSDK) Native.loadLibrary(strDllPath, HCNetSDK.class);
                }catch (Exception ex) {
                    System.out.println("loadLibrary: " + strDllPath + " Error: " + ex.getMessage());
                    return false;
                }
            }
        }
        return true;
    }

    public AjaxResult linux_init(ThDoorControl thDoorControl){
        if (osSelect.isLinux())//如果是Linux
        {
            HCNetSDK.BYTE_ARRAY ptrByteArray1 = new HCNetSDK.BYTE_ARRAY(256);
            HCNetSDK.BYTE_ARRAY ptrByteArray2 = new HCNetSDK.BYTE_ARRAY(256);
            //这里是库的绝对路径，请根据实际情况修改，注意改路径必须有访问权限
            String strPath1 = System.getProperty("user.dir") + "/lib/libcrypto.so.1.1";
            String strPath2 = System.getProperty("user.dir") + "/lib/libssl.so.1.1";

            System.arraycopy(strPath1.getBytes(), 0, ptrByteArray1.byValue, 0, strPath1.length());
            ptrByteArray1.write();
            hCNetSDK.NET_DVR_SetSDKInitCfg(3, ptrByteArray1.getPointer());

            System.arraycopy(strPath2.getBytes(), 0, ptrByteArray2.byValue, 0, strPath2.length());
            ptrByteArray2.write();
            hCNetSDK.NET_DVR_SetSDKInitCfg(4, ptrByteArray2.getPointer());

            String strPathCom = System.getProperty("user.dir") + "/lib/";
            HCNetSDK.NET_DVR_LOCAL_SDK_PATH struComPath = new HCNetSDK.NET_DVR_LOCAL_SDK_PATH();
            System.arraycopy(strPathCom.getBytes(), 0, struComPath.sPath, 0, strPathCom.length());
            struComPath.write();
            hCNetSDK.NET_DVR_SetSDKInitCfg(2, struComPath.getPointer());
        }

        hCNetSDK.NET_DVR_Init();
        //开启SDK日志打印
        boolean i= hCNetSDK.NET_DVR_SetLogToFile(3, "./sdklog", false);

        //return login_V40("192.168.1.64","admin","XTC123456789",(short) 8000);	//登陆设备
        return login_V40(thDoorControl.getIpadress(),thDoorControl.getUser(),thDoorControl.getPsw(),thDoorControl.getPort());	//登陆设备
    }

    public  AjaxResult login_V40(String ipadress, String user, String psw, short port) {
        AjaxResult ajaxResult = new AjaxResult();
        //注册
        HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();//设备登录信息
        String m_sDeviceIP = ipadress;//设备ip地址
        m_strLoginInfo.sDeviceAddress = new byte[HCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN];
        System.arraycopy(m_sDeviceIP.getBytes(), 0, m_strLoginInfo.sDeviceAddress, 0, m_sDeviceIP.length());
        String m_sUsername = user;//设备用户名
        m_strLoginInfo.sUserName = new byte[HCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];
        System.arraycopy(m_sUsername.getBytes(), 0, m_strLoginInfo.sUserName, 0, m_sUsername.length());
        String m_sPassword = psw;//设备密码
        m_strLoginInfo.sPassword = new byte[HCNetSDK.NET_DVR_LOGIN_PASSWD_MAX_LEN];
        System.arraycopy(m_sPassword.getBytes(), 0, m_strLoginInfo.sPassword, 0, m_sPassword.length());
        m_strLoginInfo.wPort = port; //sdk端口
        m_strLoginInfo.bUseAsynLogin = false; //是否异步登录：0- 否，1- 是
        m_strLoginInfo.write();
        HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();//设备信息
        //lUserID = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo);
        int loginHandler = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo);
        if (loginHandler == -1 ) {

            ajaxResult.put("code",500);
            ajaxResult.put("msg","登录失败，错误码为"+ hCNetSDK.NET_DVR_GetLastError());
            return ajaxResult;
        } else {

            loginHandleMap.put(m_sDeviceIP,loginHandler);
            ajaxResult.put("code",200);
            ajaxResult.put("msg","登录成功!");
            return ajaxResult;
        }
    }
}
